﻿/*
 DotNetNuke - http://www.dotnetnuke.com
 Copyright (c) 2002-2010 by DotNetNuke Corp.

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
 documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
 to permit persons to whom the Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all copies or substantial portions 
 of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 DEALINGS IN THE SOFTWARE.

*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

using System.Web;
using System.Xml;
using System.Xml.Serialization;

using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Modules.Definitions;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Framework;
using DotNetNuke.Security.Permissions;
using DotNetNuke.Security.Roles;
using DotNetNuke.Services.EventQueue;


namespace DotNetNuke.Modules.UserDefinedTable.Serialization
{



  public class ModuleSerializationController
  {
    private static void AddContent(XmlNode nodeModule, ModuleInfo objModule, int MaxNumberOfRecords)
    {
      if ((objModule.DesktopModule.BusinessControllerClass != "") & objModule.DesktopModule.IsPortable)
      {
        try
        {
          object objectValue = (Reflection.CreateObject(objModule.DesktopModule.BusinessControllerClass, objModule.DesktopModule.BusinessControllerClass));
          string xml = string.Empty;

          if (objectValue is IPortable2)
            xml = ((IPortable2)objectValue).ExportModule(objModule.ModuleID, objModule.TabID, MaxNumberOfRecords);
          
          else if (objectValue is IPortable)
            xml = ((IPortable)objectValue).ExportModule(objModule.ModuleID);
          
          if (xml != "")
          {
            XmlNode newChild = nodeModule.OwnerDocument.CreateElement("content");
            XmlAttribute node = nodeModule.OwnerDocument.CreateAttribute("type");
            node.Value = DotNetNuke.Common.Globals.CleanName(objModule.DesktopModule.ModuleName);
            newChild.Attributes.Append(node);
            node = nodeModule.OwnerDocument.CreateAttribute("version");
            node.Value = objModule.DesktopModule.Version;
            newChild.Attributes.Append(node);
            try
            {
              XmlDocument document = new XmlDocument();
              document.LoadXml(xml);
              newChild.AppendChild(newChild.OwnerDocument.ImportNode(document.DocumentElement, true));
            }
            catch (Exception e)
            {
              
              Exception exception = e;
              xml = System.Web.HttpContext.Current.Server.HtmlEncode(xml);
              newChild.InnerXml = XmlUtils.XMLEncode(xml);
              
            }
            nodeModule.AppendChild(newChild);
          }
        }
        catch (Exception exception2)
        { }

      }
    }

    private static void AddSettings(XmlNode nodeModule, ModuleInfo objModule)
    {
      XmlAttribute attribute;
      ModuleController controller = new ModuleController();
      Hashtable moduleSettings = controller.GetModuleSettings(objModule.ModuleID);
      Hashtable tabModuleSettings = controller.GetTabModuleSettings(objModule.TabModuleID);
      bool flag = true;
      bool flag2 = true;

      if ((objModule.DesktopModule.BusinessControllerClass != "") & objModule.DesktopModule.IsPortable)
      {
        try
        {
          object objectValue = (Reflection.CreateObject(objModule.DesktopModule.BusinessControllerClass, objModule.DesktopModule.BusinessControllerClass));
          if (objectValue is IPortable2)
          {
            flag = !((IPortable2)objectValue).ManagesModuleSettings;
            flag2 = !((IPortable2)objectValue).ManagesTabModuleSettings;
          }
        }
        catch (Exception e)
        { }

      }
      if ((moduleSettings.Count > 0) && flag)
      {
        XmlNode newChild = nodeModule.OwnerDocument.CreateElement("modulesettings");

        XmlNode node2;

        foreach (string str in moduleSettings.Keys)
        {
          node2 = nodeModule.OwnerDocument.CreateElement("setting");
          attribute = nodeModule.OwnerDocument.CreateAttribute("name");
          attribute.Value = str;
          node2.Attributes.Append(attribute);
          attribute = nodeModule.OwnerDocument.CreateAttribute("value");
          attribute.Value = (string)moduleSettings[str];
          node2.Attributes.Append(attribute);
          newChild.AppendChild(node2);
        }
        nodeModule.AppendChild(newChild);
      }
      if ((tabModuleSettings.Count > 0) && flag2)
      {
        XmlNode node3 = nodeModule.OwnerDocument.CreateElement("tabmodulesettings");

        foreach (string str2 in tabModuleSettings.Keys)
        {
          XmlNode node4 = nodeModule.OwnerDocument.CreateElement("setting");
          attribute = nodeModule.OwnerDocument.CreateAttribute("name");
          attribute.Value = str2;
          node4.Attributes.Append(attribute);
          attribute = nodeModule.OwnerDocument.CreateAttribute("value");
          attribute.Value = (string)tabModuleSettings[str2];
          node4.Attributes.Append(attribute);
          node3.AppendChild(node4);
        }
        nodeModule.AppendChild(node3);
      }
    }





    private static void CreateEventQueueMessage(ModuleInfo objModule, string strContent, string strVersion, int userID)
    {
      EventMessage message2 = new EventMessage();
      message2.Priority = MessagePriority.High;
      message2.ExpirationDate = DateTime.Now.AddYears(-1);
      message2.SentDate = DateTime.Now;
      message2.Body = "";
      message2.ProcessorType = "DotNetNuke.Entities.Modules.EventMessageProcessor, DotNetNuke";
      message2.ProcessorCommand = "ImportModule";
      EventMessage message = message2;
      message.Attributes.Add("BusinessControllerClass", objModule.DesktopModule.BusinessControllerClass);
      message.Attributes.Add("ModuleId", objModule.ModuleID.ToString());
      message.Attributes.Add("Content", strContent);
      message.Attributes.Add("Version", strVersion);
      message.Attributes.Add("UserID", userID.ToString());
      EventQueueController.SendMessage(message, "Application_Start");
    }





    private static ModuleInfo DeserializeModule(XmlNode nodeModule, XmlNode nodePane, int PortalId, int TabId, int ModuleDefId)
    {
      ModuleInfo info3 = new ModuleInfo();
      info3.PortalID = PortalId;
      info3.TabID = TabId;
      info3.ModuleOrder = -1;
      info3.ModuleTitle = XmlUtils.GetNodeValue(nodeModule, "title", "");
      info3.PaneName = XmlUtils.GetNodeValue(nodePane, "name", "");
      info3.ModuleDefID = ModuleDefId;
      info3.CacheTime = XmlUtils.GetNodeValueInt(nodeModule, "cachetime");
      info3.Alignment = XmlUtils.GetNodeValue(nodeModule, "alignment", "");
      info3.IconFile = DotNetNuke.Common.Globals.ImportFile(PortalId, XmlUtils.GetNodeValue(nodeModule, "iconfile", ""));
      info3.AllTabs = XmlUtils.GetNodeValueBoolean(nodeModule, "alltabs");
      ModuleInfo info2 = info3;
      switch (XmlUtils.GetNodeValue(nodeModule, "visibility", ""))
      {
        case "Maximized":
          info2.Visibility = VisibilityState.Maximized;
          break;

        case "Minimized":
          info2.Visibility = VisibilityState.Minimized;
          break;

        case "None":
          info2.Visibility = VisibilityState.None;
          break;
      }
      info2.Color = XmlUtils.GetNodeValue(nodeModule, "color", "");
      info2.Border = XmlUtils.GetNodeValue(nodeModule, "border", "");
      info2.Header = XmlUtils.GetNodeValue(nodeModule, "header", "");
      info2.Footer = XmlUtils.GetNodeValue(nodeModule, "footer", "");
      info2.InheritViewPermissions = XmlUtils.GetNodeValueBoolean(nodeModule, "inheritviewpermissions", false);
      info2.StartDate = XmlUtils.GetNodeValueDate(nodeModule, "startdate", Null.NullDate);
      info2.EndDate = XmlUtils.GetNodeValueDate(nodeModule, "enddate", Null.NullDate);

      if (XmlUtils.GetNodeValue(nodeModule, "containersrc", "") != "")
        info2.ContainerSrc = XmlUtils.GetNodeValue(nodeModule, "containersrc", "");
      
      info2.DisplayTitle = XmlUtils.GetNodeValueBoolean(nodeModule, "displaytitle", true);
      info2.DisplayPrint = XmlUtils.GetNodeValueBoolean(nodeModule, "displayprint", true);
      info2.DisplaySyndicate = XmlUtils.GetNodeValueBoolean(nodeModule, "displaysyndicate", false);
      info2.IsWebSlice = XmlUtils.GetNodeValueBoolean(nodeModule, "iswebslice", false);

      if (info2.IsWebSlice)
      {
        info2.WebSliceTitle = XmlUtils.GetNodeValue(nodeModule, "webslicetitle", info2.ModuleTitle);
        info2.WebSliceExpiryDate = XmlUtils.GetNodeValueDate(nodeModule, "websliceexpirydate", info2.EndDate);
        info2.WebSliceTTL = XmlUtils.GetNodeValueInt(nodeModule, "webslicettl", info2.CacheTime / 60);
      }
      return info2;
    }




    public static void DeserializeModule(XmlNode nodeModule, XmlNode nodePane, int PortalId, int TabId, PortalTemplateModuleAction mergeTabs, Hashtable hModules)
    {
      ModuleController controller = new ModuleController();
      ModuleDefinitionInfo moduleDefinition = GetModuleDefinition(nodeModule);
      int nodeValueInt = XmlUtils.GetNodeValueInt(nodeModule, "moduleID");
      bool isInstance = CheckIsInstance(nodeValueInt, hModules);
      XmlNode oldChild = nodeModule.SelectSingleNode("containersrc");

      if (oldChild != null)
      {
        string path = oldChild.Value;

        if (!File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))
          nodeModule.RemoveChild(oldChild);
        
      }
      if ((moduleDefinition != null) && !FindModule(nodeModule, TabId, mergeTabs))
      {
        int num;
        ModuleInfo objModule = DeserializeModule(nodeModule, nodePane, PortalId, TabId, moduleDefinition.ModuleDefID);
        if (!isInstance)
        {
          num = controller.AddModule(objModule);
          if (nodeValueInt > 0)
            hModules.Add(nodeValueInt, num);
          
        }
        else
        {
          objModule.ModuleID = Convert.ToInt32((hModules[nodeValueInt]));
          num = controller.AddModule(objModule);
        }

        if (XmlUtils.GetNodeValue(nodeModule, "content", "") != "")
          GetModuleContent(nodeModule, num, TabId, PortalId, isInstance);
        
        if (!isInstance)
        {
          DeserializeModulePermissions(nodeModule.SelectNodes("modulepermissions/permission"), PortalId, objModule);
          ModulePermissionController.SaveModulePermissions(objModule);
          DeserializeModuleSettings(nodeModule.SelectNodes("modulesettings/setting"), num);
        }
        DeserializeTabModuleSettings(nodeModule.SelectNodes("tabmodulesettings/setting"), num, TabId);
      }
    }




    private static void DeserializeModulePermissions(XmlNodeList nodeModulePermissions, int PortalId, ModuleInfo objModule)
    {
      RoleController controller2 = new RoleController();
      PermissionController controller = new PermissionController();

      string permissionKey, permissionCode, roleName, str4;
      bool nodeValueBoolean;
      int roleID = -2147483648;
      int permissionID;
      ArrayList permissionByCodeAndKey;
      int num4;
      ModulePermissionInfo info3, info4;

      foreach(XmlNode current in nodeModulePermissions)
      {
        permissionKey = XmlUtils.GetNodeValue(current, "permissionkey", "");
        permissionCode = XmlUtils.GetNodeValue(current, "permissioncode", "");
        roleName = XmlUtils.GetNodeValue(current, "rolename", "");
        nodeValueBoolean = XmlUtils.GetNodeValueBoolean(current, "allowaccess");
        
        str4 = roleName;
        if (str4 == "All Users")
          roleID = Convert.ToInt32("-1");
        
        else if (str4 == "Unauthenticated Users")
          roleID = Convert.ToInt32("-3");
        
        else
        {
          RoleInfo roleByName = controller2.GetRoleByName(PortalId, roleName);
          if (roleByName != null)
            roleID = roleByName.RoleID;
          
        }
        if (roleID != -2147483648)
        {
          permissionID = -1;
          permissionByCodeAndKey = controller.GetPermissionByCodeAndKey(permissionCode, permissionKey);
          num4 = permissionByCodeAndKey.Count - 1;
          for (int i = 0; i <= num4; i++)
          {
            PermissionInfo info = (PermissionInfo)permissionByCodeAndKey[i];
            permissionID = info.PermissionID;
          }
          if (permissionID != -1)
          {
            info4 = new ModulePermissionInfo();
            info4.ModuleID = objModule.ModuleID;
            info4.PermissionID = permissionID;
            info4.RoleID = roleID;
            info4.AllowAccess = nodeValueBoolean;
            info3 = info4;
            objModule.ModulePermissions.Add(info3);
          }
        }
      }
    }





    private static void DeserializeModuleSettings(XmlNodeList nodeModuleSettings, int ModuleID)
    {
      ModuleController controller = new ModuleController();
      bool flag = controller.GetModuleSettings(ModuleID).Count == 0;

      string attribute, settingValue;

      foreach (XmlElement current in nodeModuleSettings)
      {
        attribute = current.GetAttribute("name");
        settingValue = current.GetAttribute("value");
        if (flag || (current.GetAttribute("installmode").ToLowerInvariant() == "force"))
          controller.UpdateModuleSetting(ModuleID, attribute, settingValue);
        
      }
    }




    private static void DeserializeTabModuleSettings(XmlNodeList nodeTabModuleSettings, int ModuleID, int TabID)
    {
      ModuleController controller = new ModuleController();
      int tabModuleID = controller.GetModule(ModuleID, TabID).TabModuleID;
      bool flag = controller.GetTabModuleSettings(tabModuleID).Count == 0;

      string settingName, settingValue;

      foreach (XmlElement current in nodeTabModuleSettings)
      {
        settingName = current.Attributes["name"].Value;
        settingValue = current.Attributes["value"].Value;
        if (flag || (current.GetAttribute("installmode").ToLowerInvariant() == "force"))
          controller.UpdateTabModuleSetting(tabModuleID, settingName, settingValue);
          
      }
    }





    private static bool FindModule(XmlNode nodeModule, int TabId, PortalTemplateModuleAction mergeTabs)
    {
      Dictionary<int, ModuleInfo> tabModules = new ModuleController().GetTabModules(TabId);

      string str = XmlUtils.GetNodeValue(nodeModule, "title", "");
      if (mergeTabs == PortalTemplateModuleAction.Merge)
      {
        foreach (KeyValuePair<int, ModuleInfo> pair in tabModules)
        {
          ModuleInfo info = pair.Value;
          if (str == info.ModuleTitle)
            return true;
          
        }
      }
      return false;
    }




    private static void GetModuleContent(XmlNode nodeModule, int ModuleId, int TabId, int PortalId, bool isInstance)
    {
      ModuleInfo objModule = new ModuleController().GetModule(ModuleId, TabId, true);
      string strVersion = nodeModule.SelectSingleNode("content").Attributes["version"].Value;
      string innerXml = nodeModule.SelectSingleNode("content").InnerXml;
      if (innerXml.StartsWith("<![CDATA["))
      {
        innerXml = innerXml.Substring(9, innerXml.Length - 12);
        innerXml = System.Web.HttpContext.Current.Server.HtmlDecode(innerXml);
      }

      if ((objModule.DesktopModule.BusinessControllerClass != "") & (innerXml != ""))
      {
        PortalInfo portal = new PortalController().GetPortal(PortalId);
        if (objModule.DesktopModule.SupportedFeatures == Null.NullInteger)
        {
          innerXml = System.Web.HttpContext.Current.Server.HtmlEncode(innerXml);
          CreateEventQueueMessage(objModule, innerXml, strVersion, portal.AdministratorId);
        }
        else if (objModule.DesktopModule.IsPortable)
        {
          try
          {
            object objectValue = (Reflection.CreateObject(objModule.DesktopModule.BusinessControllerClass, objModule.DesktopModule.BusinessControllerClass));
            if (objectValue is IPortable2)
              ((IPortable2)objectValue).ImportModule(ModuleId, TabId, innerXml, strVersion, portal.AdministratorId, isInstance);
            
            else if ((objectValue is IPortable) && !isInstance)
              ((IPortable)objectValue).ImportModule(ModuleId, innerXml, strVersion, portal.AdministratorId);
            
          }
          catch (Exception e)
          { }

        }
      }
    }





    private static ModuleDefinitionInfo GetModuleDefinition(XmlNode nodeModule)
    {
      ModuleDefinitionInfo info3 = null;
      DesktopModuleInfo desktopModuleByModuleName = DesktopModuleController.GetDesktopModuleByModuleName(XmlUtils.GetNodeValue(nodeModule, "definition", ""), Null.NullInteger);
      if (desktopModuleByModuleName == null)
        return info3;
      
      string str = XmlUtils.GetNodeValue(nodeModule, "moduledefinition", "");
      if (string.IsNullOrEmpty(str))
      {
        using (Dictionary<string, ModuleDefinitionInfo>.ValueCollection.Enumerator enumerator = ModuleDefinitionController.GetModuleDefinitionsByDesktopModuleID(desktopModuleByModuleName.DesktopModuleID).Values.GetEnumerator())
        {
          while (enumerator.MoveNext())
            return enumerator.Current;
          
          return info3;
        }
      }
      return ModuleDefinitionController.GetModuleDefinitionByFriendlyName(str, desktopModuleByModuleName.DesktopModuleID);
    }





    private static bool CheckIsInstance(int templateModuleID, Hashtable hModules)
    {
      bool flag2 = false;
      if ((templateModuleID > 0) && (hModules[templateModuleID] != null))
        flag2 = true;
      
      return flag2;
    }





    public static XmlNode SerializeModule(XmlDocument xmlModule, ModuleInfo objModule, bool includeContent)
    {
      return SerializeModule(xmlModule, objModule, includeContent, Null.NullInteger);
    }





    public static XmlNode SerializeModule(XmlDocument xmlModule, ModuleInfo objModule, bool includeContent, int maxNumberofRecords)
    {
      XmlSerializer serializer = new XmlSerializer(typeof(ModuleInfo));
      using (StringWriter writer = new StringWriter())
      {
        serializer.Serialize((TextWriter)writer, objModule);
        xmlModule.LoadXml(writer.GetStringBuilder().ToString());
      }
      XmlNode nodeModule = xmlModule.SelectSingleNode("module");
      nodeModule.Attributes.Remove(nodeModule.Attributes["xmlns:xsd"]);
      nodeModule.Attributes.Remove(nodeModule.Attributes["xmlns:xsi"]);
      nodeModule.RemoveChild(nodeModule.SelectSingleNode("portalid"));
      nodeModule.RemoveChild(nodeModule.SelectSingleNode("tabid"));
      nodeModule.RemoveChild(nodeModule.SelectSingleNode("tabmoduleid"));
      nodeModule.RemoveChild(nodeModule.SelectSingleNode("moduleorder"));
      nodeModule.RemoveChild(nodeModule.SelectSingleNode("panename"));
      nodeModule.RemoveChild(nodeModule.SelectSingleNode("isdeleted"));

      foreach (XmlNode current in nodeModule.SelectNodes("modulepermissions/permission"))
      {
        current.RemoveChild(current.SelectSingleNode("modulepermissionid"));
        current.RemoveChild(current.SelectSingleNode("permissionid"));
        current.RemoveChild(current.SelectSingleNode("moduleid"));
        current.RemoveChild(current.SelectSingleNode("roleid"));
        current.RemoveChild(current.SelectSingleNode("userid"));
        current.RemoveChild(current.SelectSingleNode("username"));
        current.RemoveChild(current.SelectSingleNode("displayname"));
      }

      if (includeContent)
      {
        AddContent(nodeModule, objModule, maxNumberofRecords);
        AddSettings(nodeModule, objModule);
      }

      XmlNode newChild = xmlModule.CreateElement("definition");
      ModuleDefinitionInfo moduleDefinitionByID = ModuleDefinitionController.GetModuleDefinitionByID(objModule.ModuleDefID);
      newChild.InnerText = DesktopModuleController.GetDesktopModule(moduleDefinitionByID.DesktopModuleID, objModule.PortalID).ModuleName;
      nodeModule.AppendChild(newChild);
      XmlNode node2 = xmlModule.CreateElement("moduledefinition");
      node2.InnerText = moduleDefinitionByID.FriendlyName;
      nodeModule.AppendChild(node2);

      return nodeModule;
    }


  }

}

